﻿using Engine;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using Game.Server;
using Game.Server.Plugins;
using System.Globalization;
using Game.NetWork;
using LiteNetLib;
using Game.NetWork.Packages;

namespace Game
{
    public class CmdWhitelists : AbstractProcessCmd
    {
        public override string Cmd => "wls";

        public override string Introduce => "/wls  -查看白名单指令";

        public override int AuthLevel => 1000;

        public override DisplayType Display => DisplayType.Authority;

        public override void ProcessCmd()
        {
            if (GameManager.Project == null)
            {
                SendMessage(Cmd, "请先进入存档");
                return;
            }
            if (!m_isTerminal)
            {
                SendMessage(Cmd, "请在控制台使用");
                return;
            }
            if (m_messageDatas.Length >= 2)
            {
                if (m_messageDatas[1] == "add" && m_messageDatas.Length == 4)
                {
                    DateTime time = DateTime.Now;
                    try
                    {
                        time = Convert.ToDateTime(m_messageDatas[3]);
                    }
                    catch
                    {
                        SendMessage(Cmd, "输入的日期格式有误，应为：年-月-日");
                        return;
                    }
                    string[] ids = m_messageDatas[2].Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach(string g in ids)
                    {
                        WhitelistsPlugin.WhitelistsById[g] = new WhitelistsPlugin.Whitelists();
                        WhitelistsPlugin.WhitelistsById[g].Time = time;
                        WhitelistsPlugin.WhitelistsById[g].Name = "未获取";
                    }
                    SendMessage(Cmd, "白名单添加成功");
                }
                else if(m_messageDatas[1] == "rem" && m_messageDatas.Length == 3)
                {
                    if (m_messageDatas[2] == "all")
                    {
                        WhitelistsPlugin.WhitelistsById.Clear();
                    }
                    else
                    {
                        string id = m_messageDatas[2];
                        if (WhitelistsPlugin.WhitelistsById.ContainsKey(id))
                        {
                            WhitelistsPlugin.WhitelistsById.Remove(id);
                        }
                    }
                    SendMessage(Cmd, "白名单移除成功");
                }
                else if(m_messageDatas[1] == "show" && m_messageDatas.Length == 2)
                {
                    string msg = "";
                    foreach (var kv in WhitelistsPlugin.WhitelistsById)
                    {
                        msg += $"名称:{kv.Value.Name} 社区ID:{kv.Key} 到期时间:{kv.Value.Time}\n";
                    }
                    SendMessage(Cmd, msg);
                }
                else
                {
                    SendMessage(Cmd, "输入的指令有误，请检查");
                }
            }
            else
            {
                string help = "/wls add id time     -添加指定玩家,id为玩家社区ID,time为有效期\n";
                help += "/wls add id1,id2,... time   -添加多个玩家,id用英文逗号分隔\n";
                help += "/wls rem id                 -移除指定玩家,id为玩家社区ID\n";
                help += "/wls rem all                -移除全部玩家\n";
                help += "/wls show                   -展示全部名单\n";
                SendMessage(Cmd, help);
            }
        }
    }

    public class WhitelistsPlugin : ServerPlugin, IBanEventHandle
    {
        public class Whitelists
        {
            public string Name;
            public DateTime Time;
        }

        public static Dictionary<string, Whitelists> WhitelistsById = new Dictionary<string, Whitelists>();

        public override string Name => "白名单插件";

        public override int Version => 10000;

        public byte FirstLevel => 0;

        public static string WhitelistsPath;

        public override void Initialize()
        {
            BanEventManager.AddObject(this);
        }

        public string GetPluginDataByWorldPath(string fileName)
        {
            string pluginDataPath = Storage.GetSystemPath("app:/PluginData");
            if (!Directory.Exists(pluginDataPath))
            {
                Directory.CreateDirectory(pluginDataPath);
            }
            string worldName = GameManager.Project.FindSubsystem<SubsystemGameInfo>().WorldSettings.Name;
            string dataByWorldPath = Storage.CombinePaths(pluginDataPath, worldName);
            if (!Directory.Exists(dataByWorldPath))
            {
                Directory.CreateDirectory(dataByWorldPath);
            }
            return Storage.CombinePaths(dataByWorldPath, fileName);
        }

        public override void Load()
        {
            WhitelistsPath = GetPluginDataByWorldPath("Whitelists.json"); 
            try
            {
                WhitelistsById.Clear();
                if (File.Exists(WhitelistsPath))
                {
                    using (StreamReader file = File.OpenText(WhitelistsPath))
                    {
                        string jsonText = file.ReadToEnd();
                        WhitelistsById = JsonConvert.DeserializeObject<Dictionary<string, Whitelists>>(jsonText);
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error($"插件{Name}装载失败：{e.Message}");
            }
        }

        public override void Save()
        {
            try
            {
                string jsonText = JsonConvert.SerializeObject(WhitelistsById);
                using (FileStream fileStream = File.Open(WhitelistsPath, FileMode.Create))
                {
                    using (StreamWriter fileWrite = new StreamWriter(fileStream))
                    {
                        fileWrite.Write(jsonText);
                        fileWrite.Flush();
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error($"插件{Name}保存失败：{e.Message}");
            }
        }

        public bool IsBan(string nickname, string id, string ip, NetNode netNode, Client client)
        {
            if (!string.IsNullOrEmpty(id))
            {
                if(WhitelistsById.TryGetValue(id, out Whitelists value))
                {
                    value.Name = nickname;
                    if (DateTime.Now < value.Time)
                    {
                        return false;
                    }
                    else
                    {
                        netNode.SendWriterFromPackage(new ConnectionRejectPackage("你的白名单名额已过期，不可进入"), client.Request, true);
                        return true;
                    }
                }
            }
            netNode.SendWriterFromPackage(new ConnectionRejectPackage("你不在白名单内，不可进入"), client.Request, true);
            return true;
        }

        public bool IsBanIp(string ip, NetNode netNode, ConnectionRequest request)
        {
            return false;
        }
    }
}